#import "BWLabelInspectorPane.h"
#import "BWBorkStitchDocument.h"
#import "BWDocumentUndo.h"
#import "NSSegmentedControl+Additions.h"
#import "BWStitch.h"
#import "BWStitchSelection.h"
#import "BWStitchArray.h"
#import "BWConfigTemplate.h"
#import "BWConfigPopUpButton.h"


@implementation BWLabelInspectorPane

- (id) init
{
    if (self = [super init]) {
        if (![NSBundle loadNibNamed: @"BWLabelInspectorPane"
                       owner: self]) {
            NSLog (@"could not load BWLabelInspectorPane.nib");
        }
        NSNotificationCenter *center;
        center = [NSNotificationCenter defaultCenter];

        [center addObserver: self
                selector: @selector(stitchSelectionChangeNotification:)
                name: BWBorkStitchDocument_StitchSelectionChangeNotification
                object: nil];
    }

    return (self);

} // init


- (NSImage *) toolbarIcon
{
    NSImage *image;
    image = [NSImage imageNamed: @"label-pane.tiff"];

    return (image);

} // toolbarIcon


- (void) setDocument: (BWBorkStitchDocument *) d
{
    if (document != nil) {
        // unhook observer
        [[document selectedStitches]
            removeObserver: self
            forKeyPath: @"count"];
    }

    [super setDocument: d];

    if (document != nil) {
        [[document selectedStitches]
            addObserver: self
            forKeyPath: @"count"
            options: 0
            context: NULL];
    }

} // setDocument


- (void) observeValueForKeyPath: (NSString *) keyPath
                       ofObject: (id) object
                         change: (NSDictionary *) change
                        context: (void *) context
{
    // selection changed
    if ([keyPath isEqualToString: @"count"]) {
        [self updateUI];

    } else {
        [super observeValueForKeyPath: keyPath
               ofObject: object
               change: change
               context: context];
    }
    
} // observeValueForKeyPath



// --------------------------------------------------
// UI foobage

- (void) setupLabelLocationSegmentedControl: (NSSegmentedControl *) seggie
                                   tagStart: (int) tagStart
{
    [seggie setSegmentCount: 2];
    
    [seggie setLabel: @"Inside"  forSegment: 0];
    [seggie setLabel: @"Outside"  forSegment: 1];

    // these are from a category
    [seggie setTag: tagStart + 0  forSegment: 0];
    [seggie setTag: tagStart + 1  forSegment: 1];

    [seggie setTrackingMode: NSSegmentSwitchTrackingSelectOne];

    [seggie setControlSize: NSSmallControlSize];

} // setupLabelLocationSegmentedControl


enum ShowLabelsSegments {
    kBothSegment = 0,
    kStartSegment = 1,
    kEndSegment = 2,
    kNoneSegment = 3
};

- (void) setupLabelDisplaySegmentedControl: (NSSegmentedControl *) seggie
{
    [seggie setSegmentCount: 4];
    
    [seggie setLabel: @"Both"  forSegment: kBothSegment];
    [seggie setLabel: @"Start"  forSegment: kStartSegment];
    [seggie setLabel: @"End"  forSegment: kEndSegment];
    [seggie setLabel: @"None"  forSegment: kNoneSegment];

    // these are from a category
    [seggie setTag: kBothSegment  forSegment: kBothSegment];
    [seggie setTag: kStartSegment  forSegment: kStartSegment];
    [seggie setTag: kEndSegment  forSegment: kEndSegment];
    [seggie setTag: kNoneSegment  forSegment: kNoneSegment];

    [seggie setTrackingMode: NSSegmentSwitchTrackingSelectOne];

    [seggie setControlSize: NSSmallControlSize];

} // setupLabelDisplaySegmentedControl


- (void) awakeFromNib
{
    // NSSegmentedControl isn't available in IB in 10.3.  Can we change this
    // in tigger?

    [self setupLabelLocationSegmentedControl: startLocationSegmentedControl
          tagStart: 0];
    [self setupLabelLocationSegmentedControl: endLocationSegmentedControl
          tagStart: 2];

    [self setupLabelDisplaySegmentedControl: showLabelsSegmentedControl];

    NSFont *font;
    font = [NSFont systemFontOfSize: [NSFont smallSystemFontSize]];

    [showLabelsSegmentedControl setControlSize: NSMiniControlSize];
    [showLabelsSegmentedControl setFont: font];
    [startLocationSegmentedControl setControlSize: NSMiniControlSize];
    [startLocationSegmentedControl setFont: font];
    [endLocationSegmentedControl setControlSize: NSMiniControlSize];
    [endLocationSegmentedControl setFont: font];

} // stitchControlsAwakeFromNib



- (void) getLabelCountForStartInside: (int *) startInsideCount
                             outside: (int *) startOutsideCount
                           endInside: (int *) endInsideCount
                             outside: (int *) endOutsideCount
{
    *startInsideCount = *startOutsideCount = 0;
    *endInsideCount = *endOutsideCount = 0;

    NSEnumerator *enumerator = [[document selectedStitches] objectEnumerator];

    BWStitch *stitch;
    while (stitch = [enumerator nextObject]) {

        // originally had checks for visiblity, but it didn't make
        // much sense.  Granted, you could be seeing/setting a value 
        // for a label that's not there, but the user may be 
        // changing lots of settings, and if the order isn't just
        // right, would get unexpected results.
        // at least that's my story right now. 9/14/05

        if ([stitch startLabelInsideStitch]) {
            (*startInsideCount)++;
        } else {
            (*startOutsideCount)++;
        }

        if ([stitch endLabelInsideStitch]) {
            (*endInsideCount)++;
        } else {
            (*endOutsideCount)++;
        }
    }

} // getLabelCountForInside


- (void) updateStartEndLocationControls
{
    int startInsideCount, startOutsideCount;
    int endInsideCount, endOutsideCount;

    [self getLabelCountForStartInside: &startInsideCount
          outside: &startOutsideCount
          endInside: &endInsideCount
          outside: &endOutsideCount];

    [startLocationSegmentedControl unselectAllSegments];
    [endLocationSegmentedControl unselectAllSegments];
    [startLocationSegmentedControl setEnabled: YES];
    [endLocationSegmentedControl setEnabled: YES];

    // update the start seggie
    if (startInsideCount > 0 && startOutsideCount == 0) {
        [startLocationSegmentedControl selectItemWithTag: 0];
        
    } else if (startOutsideCount > 0 && startInsideCount == 0) {
        [startLocationSegmentedControl selectItemWithTag: 1];
    }

    // update the end seggie
    if (endInsideCount > 0 && endOutsideCount == 0) {
        [endLocationSegmentedControl selectItemWithTag: 2];
        
    } else if (endOutsideCount > 0 && endInsideCount == 0) {
        [endLocationSegmentedControl selectItemWithTag: 3];
    }

    // disable if nothing selected.  no exposed bindings for enabling
    if ([[document selectedStitches] count] == 0) {
        [startLocationSegmentedControl setEnabled: NO];
        [endLocationSegmentedControl setEnabled: NO];
    }

} // updateStartEndLocationControls


- (void) getShowLabelCountForStart: (int *) startCount
                               end: (int *) endCount
                              both: (int *) bothCount
                              none: (int *) noneCount
{
    *startCount = *endCount = *bothCount = *noneCount = 0;

    NSEnumerator *enumerator = [[document selectedStitches] objectEnumerator];

    BWStitch *stitch;
    while (stitch = [enumerator nextObject]) {
        BOOL startVisible = [stitch startLabelVisibility];
        BOOL endVisible = [stitch endLabelVisibility];

        if (startVisible && !endVisible) {
            (*startCount)++;
        } else if (endVisible && !startVisible) {
            (*endCount)++;
        } else if (startVisible && endVisible) {
            (*bothCount)++;
        } else {
            (*noneCount)++;
        }
    }

} // getShowLabelCountForStart


- (void) updateShowLabelsControl
{
    int startCount, endCount, bothCount, noneCount;

    [self getShowLabelCountForStart: &startCount
          end: &endCount
          both: &bothCount
          none: &noneCount];

    [showLabelsSegmentedControl unselectAllSegments];
    [showLabelsSegmentedControl setEnabled: YES];

    if (startCount != 0 && endCount + bothCount + noneCount == 0) {
        [showLabelsSegmentedControl selectItemWithTag: kStartSegment];
    }
    if (endCount != 0 && startCount + bothCount + noneCount == 0) {
        [showLabelsSegmentedControl selectItemWithTag: kEndSegment];
    }
    if (bothCount != 0 && startCount + endCount + noneCount == 0) {
        [showLabelsSegmentedControl selectItemWithTag: kBothSegment];
    }
    if (noneCount != 0 && startCount + endCount + bothCount == 0) {
        [showLabelsSegmentedControl selectItemWithTag: kNoneSegment];
    }
    
    if ([[document selectedStitches] count] == 0) {
        [showLabelsSegmentedControl setEnabled: NO];
    }

} // updateShowLabelsControl


// If all selected stitches have the same start label, this returns
// it.  Otherwise returns nil

- (void) getCustomStartLabel: (NSString **) startLabel
              hasCustomStart: (BOOL *) hasCustomStartLabel
                    endLabel: (NSString **) endLabel
                hasCustomEnd: (BOOL *) hasCustomEndLabel
{
    *startLabel = *endLabel = nil;
    *hasCustomStartLabel = *hasCustomEndLabel = NO;

    NSEnumerator *enumerator;
    BWStitch *stitch;

    enumerator = [[document selectedStitches] objectEnumerator];

    while (stitch = [enumerator nextObject]) {
        NSString *label = [stitch customStartLabel];

        if (label != nil) {
            *hasCustomStartLabel = YES;
        }

        if (*startLabel != nil && label == nil) {
            *startLabel = nil;
            break;
        }

        if (*startLabel != nil
            && ![*startLabel isEqualToString: label]) {
            *startLabel = nil;
            break;
        }
        *startLabel = label;
    }

    enumerator = [[document selectedStitches] objectEnumerator];

    while (stitch = [enumerator nextObject]) {
        NSString *label = [stitch customEndLabel];

        if (label != nil) {
            *hasCustomEndLabel = YES;
        }

        if (*endLabel != nil && label == nil) {
            *endLabel = nil;
            break;
        }

        if (*endLabel != nil
            && ![*endLabel isEqualToString: label]) {
            *endLabel = nil;
            break;
        }
        *endLabel = label;
    }

} // getCustomStartLabel



- (void) updateCustomLabelControls
{
    NSString *startLabel, *endLabel;
    BOOL startCustom, endCustom;

    [self getCustomStartLabel: &startLabel
          hasCustomStart: &startCustom
          endLabel: &endLabel
          hasCustomEnd: &endCustom];

    if (startLabel == nil) {
        [labelStart setStringValue: @""];
    } else {
        [labelStart setStringValue: startLabel];
    }

    if (endLabel == nil) {
        [labelEnd setStringValue: @""];
    } else {
        [labelEnd setStringValue: endLabel];
    }

    if (startCustom || endCustom) {
        [removeCustomLabelButton setEnabled: YES];
    } else {
        [removeCustomLabelButton setEnabled: NO];
    }

} // updateCustomLabelControls


// refactor these two into one method please

- (void) getDisplacement: (float *) displacement
                 uniform: (BOOL *) displacementUniform
                   angle: (float *) angle
                 uniform: (BOOL *) angleUniform
                   start: (BOOL) start
{
    *displacement = *angle = 0.0;
    *displacementUniform = *angleUniform = YES;

    BOOL firstTime = YES;
    
    NSEnumerator *enumerator;
    enumerator = [[document selectedStitches] objectEnumerator];

    // for making avergages, in the non-uniform case
    float displacementSum = 0.0;
    float angleSum = 0.0;

    BWStitch *stitch;
    while (stitch = [enumerator nextObject]) {
        float disp, ang;

        if (start) {
            disp = [stitch startLabelDisplacement];
            ang = [stitch startLabelDisplacementAngle];
        } else {
            disp = [stitch endLabelDisplacement];
            ang = [stitch endLabelDisplacementAngle];
        }

        displacementSum += disp;
        angleSum += ang;

        if (firstTime) {
            firstTime = NO;
            *displacement = disp;
            *angle = ang;
            continue;
        }

        // yes, doing floating point (in)equality.  The idea is if the
        // user is spinning the dial, everyone will have the
        // exact same value

        if (*displacement != disp) {
            *displacementUniform = NO;
        }
        if (*angle != ang) {
            *angleUniform = NO;
        }
    }

    // udderwise, take the average
    if (!*displacementUniform) {
        *displacement = displacementSum / [[document selectedStitches] count];
    }

    if (!*angleUniform) {
        *angle = angleSum / [[document selectedStitches] count];
    }
    
} // getDisplacement


- (void) updateLabelOffsetControls
{
    float startDisplacement = 0.0, startDisplacementAngle = 0.0;
    float endDisplacement = 0.0, endDisplacementAngle = 0.0;
    BOOL startDisplacementUniform, endDisplacementUniform;
    BOOL startDisplacementAngleUniform, endDisplacementAngleUniform;

    [self getDisplacement: &startDisplacement
          uniform: &startDisplacementUniform
          angle: &startDisplacementAngle
          uniform: &startDisplacementAngleUniform
          start: YES];

    [self getDisplacement: &endDisplacement
          uniform: &endDisplacementUniform
          angle: &endDisplacementAngle
          uniform: &endDisplacementAngleUniform
          start: NO];

    [startLabelDisplacementSlider
        setFloatValue: startDisplacement];
    [endLabelDisplacementSlider
        setFloatValue: endDisplacement];

    [startLabelDisplacementDial
        setFloatValue: startDisplacementAngle];
    [endLabelDisplacementDial
        setFloatValue: endDisplacementAngle];

    int startInside, startOutside, endInside, endOutside;

    [self getLabelCountForStartInside: &startInside
          outside: &startOutside
          endInside: &endInside
          outside: &endOutside];

    BOOL isSelection = ([[document selectedStitches] count]) ? YES : NO;

    if (startInside > 0 && startOutside == 0) {
        [startLabelDisplacementDial setEnabled: NO];
    } else {
        [startLabelDisplacementDial setEnabled: isSelection];
    }

    if (endInside > 0 && endOutside == 0) {
        [endLabelDisplacementDial setEnabled: NO];
    } else {
        [endLabelDisplacementDial setEnabled: isSelection];
    }

} // updateLabelOffsetControls



- (void) updateUI
{
    if (document == nil) {
        return;
    }

    [self updateCustomLabelControls];
    [self updateStartEndLocationControls];
    [self updateShowLabelsControl];
    [self updateLabelOffsetControls];

} // updateUI



- (IBAction) stitchSetStartLabel: (id) sender
{
    NSString *label;
    label = [sender stringValue];

    // don't have random tabbing obliterate existing labels
    if ([label length] == 0) {
        return;
    }

    NSIndexSet *indexes;
    indexes = [[document selectedStitches] indexesForSelection];

    [document setCustomStartLabel: label
              forIndexes: indexes];

} // stitchSetStartLabel


- (IBAction) stitchSetEndLabel: (id) sender
{
    NSString *label;
    label = [sender stringValue];

    // don't have random tabbing obliterate existing labels
    if ([label length] == 0) {
        return;
    }

    NSIndexSet *indexes;
    indexes = [[document selectedStitches] indexesForSelection];

    [document setCustomEndLabel: label
              forIndexes: indexes];

} // stitchSetEndLabel


- (IBAction) stitchSetLabelVisibility: (id) sender
{
    int tag;
    tag = [sender tagForSelectedSegment];

    NSIndexSet *indexes;
    indexes = [[document selectedStitches] indexesForSelection];

    switch (tag) {
    case kBothSegment: {
        [document setStartLabelVisibility: YES
                  endLabelVisibility: YES
                  forIndexes: indexes];
        break;
    }
    case kStartSegment: {
        [document setStartLabelVisibility: YES
                  endLabelVisibility: NO
                  forIndexes: indexes];
        break;
    }
    case kEndSegment: {
        [document setStartLabelVisibility: NO
                  endLabelVisibility: YES
                  forIndexes: indexes];
        break;
    }
    case kNoneSegment: {
        [document setStartLabelVisibility: NO
                  endLabelVisibility: NO
                  forIndexes: indexes];
        break;
    }
    }

    [document setNeedsDisplay: YES];
    [self updateUI];
    [document updateChangeCount: NSChangeDone];
    
} // stitchSetLabelVisibility

    
- (IBAction) stitchSetLabelLocation: (id) sender
{
    if ([[document selectedStitches] count] == 0) {
        return;
    }

    int tag;
    tag = [sender tagForSelectedSegment];

    NSIndexSet *indexes;
    indexes = [[document selectedStitches] indexesForSelection];

    switch (tag) {
    case 0: { // start inside
        [document setStartLabelInside: YES
                  forIndexes: indexes];
        break;
    }
    case 1: { // start 
        [document setStartLabelInside: NO
                  forIndexes: indexes];
        break;
    }
    case 2: { // end inside
        [document setEndLabelInside: YES
                  forIndexes: indexes];
                 
        break;
    }
    case 3: { // end outside
        [document setEndLabelInside: NO
                  forIndexes: indexes];
        break;
    }
    }

    [document setNeedsDisplay: YES];
    [self updateUI];
    [document updateChangeCount: NSChangeDone];

} // stitchSetLabelLocation


- (IBAction) stitchRemoveCustomLabels: (id) sender
{
    [labelStart setStringValue: @""];
    [labelEnd setStringValue: @""];

    NSIndexSet *indexes;
    indexes = [[document selectedStitches] indexesForSelection];

    [document removeCustomLabelsForIndexes: indexes];

} // stitchRemoveCustomLabels



- (IBAction) stitchSetLabelDisplacement: (id) sender
{
    float newValue = 0.0;

    int tag;
    tag = [sender tag];

    NSIndexSet *indexes;
    indexes = [[document selectedStitches] indexesForSelection];

    switch (tag) {
    case 0:
        newValue = [sender floatValue];
        [document changeStartLabelDisplacementAngle: newValue
                  forIndexes: indexes];
        break;

    case 1:
        newValue = [sender floatValue];
        [document changeEndLabelDisplacementAngle: newValue
                  forIndexes: indexes];
        break;

    case 2: // the zero button
        [document changeStartLabelDisplacement: 0.0
                  forIndexes: indexes];
        [document changeEndLabelDisplacement: 0.0
                  forIndexes: indexes];
        [document changeStartLabelDisplacementAngle: 0.0
                  forIndexes: indexes];
        [document changeEndLabelDisplacementAngle: 0.0
                  forIndexes: indexes];
        break;

    case 3: // slider
        newValue = [sender floatValue];
        [document changeStartLabelDisplacement: newValue
                  forIndexes: indexes];
        break;

    case 4:
        newValue = [sender floatValue];
        [document changeEndLabelDisplacement: newValue
                  forIndexes: indexes];
        break;
    }

    [document setNeedsDisplay: YES];
    [document updateChangeCount: NSChangeDone];

} // stitchSetLabelDisplacement



- (IBAction) stitchSetLabelFont: (id) sender
{
    NSFontPanel *fontPanel;
    fontPanel = [NSFontPanel sharedFontPanel];

    [fontPanel makeKeyAndOrderFront: self];
    [fontPanel setDelegate: self];
    [fontPanel setDelegate: document];
    [fontPanel setPanelFont: [document labelFont]
               isMultiple: NO];
    
    [self updateUI];
    [document updateChangeCount: NSChangeDone];

} // stitchSetLabelFont


- (void) applyLabelAttributesToStitch: (BWStitch *) stitch
{
    [stitch setCustomStartLabel: [[document targetStitch] customStartLabel]];
    [stitch setCustomEndLabel: [[document targetStitch] customEndLabel]];

    float val;
    val = [[document targetStitch] startLabelDisplacementAngle];
    [stitch setStartLabelDisplacementAngle: val];

    val = [[document targetStitch] startLabelDisplacement];
    [stitch setStartLabelDisplacement: val];

    val = [[document targetStitch] endLabelDisplacementAngle];
    [stitch setEndLabelDisplacementAngle: val];

    val = [[document targetStitch] endLabelDisplacement];
    [stitch setEndLabelDisplacement: val];
        
    int tag;

    tag = [showLabelsSegmentedControl tagForSelectedSegment];

    switch (tag) {
    case 0:
        [stitch setStartLabelVisibility: YES];
        [stitch setEndLabelVisibility: YES];
        break;
    case 1:
        [stitch setStartLabelVisibility: YES];
        [stitch setEndLabelVisibility: NO];

        break;
    case 2:
        [stitch setStartLabelVisibility: NO];
        [stitch setEndLabelVisibility: YES];
        break;
    case 3:
        [stitch setStartLabelVisibility: NO];
        [stitch setEndLabelVisibility: NO];
        break;
    }

    tag = [startLocationSegmentedControl tagForSelectedSegment];

    switch (tag) {
    case 0: 
        [document setStartLabelInside: YES
                  forStitch: stitch];
        break;
    case 1:
        [document setStartLabelInside: NO
                  forStitch: stitch];
        break;
    }
        
    tag = [endLocationSegmentedControl tagForSelectedSegment];

    switch (tag) {
    case 2: 
        [document setEndLabelInside: YES
                  forStitch: stitch];
        break;
    case 3:
        [document setEndLabelInside: NO
                  forStitch: stitch];
        break;
    }

} // applyLabelAttributesToStitch


- (IBAction) stitchApplyLabelAttributesToAll: (id) sender
{
    NSEnumerator *enumerator;
    enumerator = [[document stitches] objectEnumerator];

    BWStitch *stitch;
    while (stitch = [enumerator nextObject]) {
        [self applyLabelAttributesToStitch: stitch];
    }
    [self applyLabelAttributesToStitch: [document templateStitch]];

    [document setNeedsDisplay: YES];
    [document updateChangeCount: NSChangeDone];

} // stitchApplyLabelAttributesToAll


- (void) stitchSelectionChangeNotification: (NSNotification *) notification
{
    [self updateUI];

} // stitchSelcetionChangeNotification


- (NSString *) paneName
{
    return (@"BWLabelInspectorPane");
} // name



// --------------------------------------------------
// config pop up button delegate methods

- (NSString *) nameForConfigPopUpButton: (BWConfigPopUpButton *) button
{
    return (@"Label Templates...");

} // nameForConfigPopUpButton


- (NSString *) categoryNameForPopUpButton: (BWConfigPopUpButton *) button
{
    return (@"Label Templates");
} // categoryNameForPopu


- (NSWindow *) windowForConfigSheetForPopUpButton: (BWConfigPopUpButton *) button
{
    return ([paneView window]);

} // windowForConfigSheetForPopUpButtonAndBoytIsThisNameEntirelyTooLong


- (void) populateTemplate: (BWConfigTemplate *) template
           forPopUpButton: (BWConfigPopUpButton *) button
{
    // --------------------------------------------------

    NSString *startLabel, *endLabel;
    BOOL startCustom, endCustom;

    [self getCustomStartLabel: &startLabel
          hasCustomStart: &startCustom
          endLabel: &endLabel
          hasCustomEnd: &endCustom];

    if (startLabel != nil) {
        [template setStringValue: startLabel
                  forKey: @"Start Label"];
    }
    [template setBoolValue: startCustom
              forKey: @"Custom Start"];
    if (endLabel != nil) {
        [template setStringValue: endLabel
                  forKey: @"End Label"];
    }
    [template setBoolValue: endCustom
              forKey: @"Custom End"];

    // --------------------------------------------------

    float startDisplacement = 0.0, startDisplacementAngle = 0.0;
    float endDisplacement = 0.0, endDisplacementAngle = 0.0;
    BOOL startDisplacementUniform, endDisplacementUniform;
    BOOL startDisplacementAngleUniform, endDisplacementAngleUniform;

    [self getDisplacement: &startDisplacement
          uniform: &startDisplacementUniform
          angle: &startDisplacementAngle
          uniform: &startDisplacementAngleUniform
          start: YES];

    [self getDisplacement: &endDisplacement
          uniform: &endDisplacementUniform
          angle: &endDisplacementAngle
          uniform: &endDisplacementAngleUniform
          start: NO];

    [template setFloatValue: startDisplacement
              forKey: @"Start Displacement"];
    [template setFloatValue: startDisplacementAngle
              forKey: @"Start Displacement Angle"];
    [template setFloatValue: endDisplacement
              forKey: @"End Displacement"];
    [template setFloatValue: endDisplacementAngle
              forKey: @"End Displacement Angle"];

    // ---------------------------------------------------

    int startLocation, endLocation;

    startLocation = [startLocationSegmentedControl tagForSelectedSegment];
    [template setIntValue: startLocation
              forKey: @"Start Location"];

    endLocation = [endLocationSegmentedControl tagForSelectedSegment];
    [template setIntValue: endLocation
              forKey: @"End Location"];

    int showLabels;
    showLabels = [showLabelsSegmentedControl tagForSelectedSegment];
    [template setIntValue: showLabels
              forKey: @"Show Labels"];

    // --------------------------------------------------

    NSFont *labelFont = [document labelFont];

    [template setObjectValue: labelFont
              forKey: @"Label Font"];

} // populateTemplateForPopUpButton


- (void) useTemplate: (BWConfigTemplate *) template
     fromPopUpButton: (BWConfigPopUpButton *) button
{

    NSIndexSet *indexes;
    indexes = [[document selectedStitches] indexesForSelection];

    BOOL customStart, customEnd;
    BOOL startVisible, endVisible, startInside, endInside;
    NSString *startLabel = nil, *endLabel = nil;
    float startDisplacement, endDisplacement, startAngle, endAngle;

    // --------------------------------------------------
    
    customStart = [template boolValueForKey: @"Custom Start"];
    if (customStart) {
        startLabel = [template stringValueForKey: @"Start Label"];
    }

    customEnd = [template boolValueForKey: @"Custom End"];
    if (customEnd) {
        endLabel = [template stringValueForKey: @"End Label"];
    }

    // --------------------------------------------------

    startDisplacement = [template floatValueForKey: @"Start Displacement"];
    endDisplacement = [template floatValueForKey: @"End Displacement"];
    startAngle = [template floatValueForKey: @"Start Displacement Angle"];
    endAngle = [template floatValueForKey: @"End Displacement Angle"];

    // --------------------------------------------------

    int startLocation, endLocation, showLabels;
    startLocation = [template intValueForKey: @"Start Location"];
    endLocation = [template intValueForKey: @"End Location"];
    showLabels = [template intValueForKey: @"Show Labels"];

    if (startLocation == 0) {
        startInside = YES;
    } else {
        startInside = NO;
    }

    if (endLocation == 2) {
        endInside = YES;
    } else {
        endInside = NO;
    }

    switch (showLabels) {
    case kBothSegment:
        startVisible = YES;
        endVisible = YES;
        break;
    case kStartSegment:
        startVisible = YES;
        endVisible = NO;
        break;
    case kEndSegment:
        startVisible = NO;
        endVisible = YES;
        break;
    case kNoneSegment:
        startVisible = NO;
        endVisible = NO;
        break;
    }

    NSFont *labelFont;
    labelFont = [template objectValueForKey: @"Label Font"];

    [document setLabelFont: labelFont];

    // --------------------------------------------------

    // write an undo method for setting everything
    [document setStartLabelVisibility: startVisible
              endLabelVisibility:  endVisible
              customStartLabel: startLabel
              customEndLabel: endLabel
              startLabelInside: startInside
              endLabelInside: endInside
              startLabelDisplacement: startDisplacement
              endLabelDisplacement: endDisplacement
              startLabelDisplacementAngle: startAngle
              endLabelDisplacementAngle: endAngle
              forIndexes: indexes];
    
} // useTemplate


@end // BWLabelInspectorPane
